//
//  LocalResourceHandler.m
//  ASFDemo
//
//  Created by Marcus on 2/22/13.
//  Copyright (c) 2013 Marcus. All rights reserved.
//

#import "LocalResourceHandler.h"
#import "HashUtility.h"
#import "Constants.h"
#import "Config.h"
#import "WebResource.h"
#import "ShareData.h"
#import "ARVideo.h"
#import "ARDatabase.h"
#import "ARResource.h"
#import "Reachability.h"

@interface LocalResourceHandler ()

@property (nonatomic, copy) NSString *resourcePath;

@end

@implementation LocalResourceHandler

@synthesize delegate;

- (id)init {
    if (self = [super init]) {
        resourceDownloadQueue = [[NSMutableArray alloc] init];
    }
    return self;
}

- (void)verifyLocalResource {
     [self downloadCheckSum];
}

- (void)downloadCheckSum {
    ChaosRequest *request = [[ChaosRequest alloc] init];
    
    request.connectionURLString = CONFIG_DOWNLOAD_LOC;
    request.delegate = self;
    request.httpMethod = @"GET";
    request.requestIdentifier = @"downloadChecksum";
    [[ChaosAgent sharedAgent] inqueue:request];
    [request release];
}

- (void)downloadNextResource {
   
    if ([resourceDownloadQueue count]>0) {

        
        ChaosRequest *request = [[ChaosRequest alloc] init];
        id resource = [resourceDownloadQueue objectAtIndex:0];
        
        if ([resource isKindOfClass:[WebResource class]]) {
            request.connectionURLString = [(WebResource *)resource zipURL];
        }
        if ([resource isKindOfClass:[ARDatabase class]]) {
            request.connectionURLString = [(ARDatabase *)resource zipURL];
        }
        if ([resource isKindOfClass:[ARVideo class]]) {
            request.connectionURLString = [(ARVideo *)resource zipURL];
        }
        request.delegate = self;
        request.httpMethod = @"GET";
        request.requestIdentifier = @"downloadResource";
        [[ChaosAgent sharedAgent] inqueue:request];
        [request release];

    }
    
}

- (void)startDoneWebResource {
    if (delegate && [delegate respondsToSelector:@selector(startFetchWebResource)]) {
        [delegate startFetchWebResource];
    }
    [self downloadNextResource];
}

#pragma mark-
#pragma ChaosConnectionDelegate
- (void)response:(ChaosResponse *)resp {
    Config *config;
    if ([resp.requestIdentifier isEqualToString:@"downloadResource"]) {
        if (resp.httpStatusCode == 200) {
            if (resp.responseData) {
                ChaosFile *file = [[ChaosFile alloc] init];
                file.fileName = [[resourceDownloadQueue objectAtIndex:0] fileName];
                if ([[[HashUtility getSHA512Hash:resp.responseData] lowercaseString] isEqualToString:[[[resourceDownloadQueue objectAtIndex:0] hashCode] lowercaseString]]) {
                    [[ChaosFileFetcher sharedFetcher] cacheFile:file withData:resp.responseData];
                    if ([file.fileName rangeOfString:@".zip"].location != NSNotFound) {
                         [[ChaosFileFetcher sharedFetcher] unZipFile:file];
                    }
                    [resourceDownloadQueue removeObjectAtIndex:0];
                    if ([resourceDownloadQueue count] > 0) {
                        [self downloadNextResource];
                    } else {
                        [self fetchDone];
                    }
                } else {
                    DebugLog(@"file: %@ checksum error,response data checksum :%@, config checksum :%@",file.fileName,[[HashUtility getSHA512Hash:resp.responseData] lowercaseString], [[[resourceDownloadQueue objectAtIndex:0] hashCode] lowercaseString]);
                    [self fetchResourceError];
                }
            } else {
                DebugLog(@"response data is null");
                [self fetchResourceError];
            }
        } else {
            DebugLog(@"connection failed with status code %d",resp.httpStatusCode);
            [self fetchResourceError];
        }
    } else {
        if (resp.httpStatusCode == 200) {
            if (resp.responseData) {
        
                config = [Config parserConfigObjectWithJson:resp.jsonDictionary];
//                NSData *udObject = [NSKeyedArchiver archivedDataWithRootObject:config];
                NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
                [ud setObject:resp.jsonDictionary forKey:@"config"];
                [ud synchronize];
                
                [[ShareData shareInstance] setLastConfigUpdateDate];
                
                if (![self isVersionUpgrade]) {
                    [self getExpectedResoureSize];
                    if (expectedLength > 0) {
                        if ([[Reachability reachabilityForInternetConnection] currentReachabilityStatus]==NotReachable)
                        {
                            [self fetchResourceError];
                        } else  if ([[Reachability reachabilityForInternetConnection] currentReachabilityStatus]==ReachableViaWiFi)
                        {
                            [self startDoneWebResource];
                        } else {
                            [self showNotifyAlert:expectedLength];
                        }
                    } else {
                        [self checkAndUnzipLocalFile];
                        [self fetchDone];
                    }
                } else {
                    [self startUpgradeApp];
                }
                
            } else {
                [self fetchResourceError];
            }
        } else {
            [self fetchResourceError];
        }
    }
}

- (void)receiveDataLength:(NSInteger)receivedDataLength identifer:(NSString *)identifer{
    if ([identifer isEqualToString:@"downloadResource"]) {
        currentReceivedLength += receivedDataLength;
        if (delegate && [delegate respondsToSelector:@selector(updateFetchWebResourceProgress:)]) {
            [delegate updateFetchWebResourceProgress:(float)currentReceivedLength/(expectedLength*1.3)];
        }
    }
}


- (void)fetchDone{
    if (delegate && [delegate respondsToSelector:@selector(updateFetchWebResourceProgress:)]) {
        [delegate updateFetchWebResourceProgress:100];
    }
    if (delegate && [delegate respondsToSelector:@selector(fetchResourceDone)]) {
        [delegate performSelector:@selector(fetchResourceDone)];
    }
}

- (void)fetchResourceError {
    if (delegate && [delegate respondsToSelector:@selector(fetchResourceError)]) {
        [delegate performSelector:@selector(fetchResourceError)];
    }
}

- (void)checkAppUpgrade {
    if ([self isVersionUpgrade]) {
        [self startUpgradeApp];
    }
}

- (BOOL)isVersionUpgrade {
    
    BOOL needUpgrade = NO;
    
    Config *config = [Config parserConfigObjectWithJson:[[NSUserDefaults standardUserDefaults] objectForKey:@"config"]];
    
    NSString *currentVersion = [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString *)kCFBundleVersionKey];
    NSString *appStoreVersion = config.appVersion;
    if ([appStoreVersion compare:currentVersion options:NSNumericSearch] == NSOrderedDescending) {
        needUpgrade = YES;
    }
    
    return needUpgrade;
}

- (void)startUpgradeApp {
    NSString *title = @"";
    NSString *message = @"Changes have been made to the App that require you to update the app before continuing";
    NSString *cancelButtonTitle = @"OK";
    UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:title message:message delegate:self cancelButtonTitle:cancelButtonTitle otherButtonTitles:nil];
    alertView.tag = 1001;
    [alertView show];
    [alertView release];
}

- (void)showNotifyAlert:(float)size {
    NSString *title = @"New Update";
    NSString *message = [NSString stringWithFormat: @"To continue using the app, you must download an %d MB update. We have detected that your device is not connectd to WiFi, do you wish to download it now?",(int)size/1024];
    NSString *cancelButtonTitle = @"Later";
    NSString *retryButtonTitle = @"OK";
    UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:title message:message delegate:self cancelButtonTitle:cancelButtonTitle otherButtonTitles:retryButtonTitle,nil];
    alertView.tag = 1002;
    [alertView show];
    [alertView release];
}

- (void )getExpectedResoureSize {
    
    Config *config = [Config parserConfigObjectWithJson:[[NSUserDefaults standardUserDefaults] objectForKey:@"config"]];
    expectedLength = 0;
    
    for (WebResource *webResource in config.webResources) {
        if (webResource.needDownloadUpdate) {
            [resourceDownloadQueue addObject:webResource];
            expectedLength += webResource.size;
        }
    }
    
    if (config.arResource.arDataBase.needDownloadUpdate) {
        [resourceDownloadQueue addObject:config.arResource.arDataBase];
        expectedLength += config.arResource.arDataBase.size;
    }
    
    for (ARVideo *webResource in config.arResource.arVideos) {
        if (webResource.needDownloadUpdate) {
            [resourceDownloadQueue addObject:webResource];
            expectedLength += webResource.size;
        }
    }
}

- (void)checkAndUnzipLocalFile {
    
    Config *config = [Config parserConfigObjectWithJson:[[NSUserDefaults standardUserDefaults] objectForKey:@"config"]];
    
    NSMutableArray *tempArrary = [[NSMutableArray alloc] init];
    
    for (WebResource *webResource in config.webResources) {
        if (![webResource isUnzipped]) {
            [tempArrary addObject:webResource];
        }
    }
    
    if (config.arResource.arDataBase) {
        if (![config.arResource.arDataBase isUnzipped]) {
            [tempArrary addObject:config.arResource.arDataBase];
        }
    }

    for (ZipResource *resource in tempArrary) {
        ChaosFile *file = [[ChaosFile alloc] init];
        file.fileName = [NSString stringWithFormat:@"%@.zip",[resource fileName]];
        [[ChaosFileFetcher sharedFetcher] unZipFile:file];
    }
}

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
    if (buttonIndex == 0) {
        if (alertView.tag == 1001) {
            [[UIApplication sharedApplication] openURL:[NSURL URLWithString:[[[ShareData shareInstance] getConfig] appUpgradeLink]]];
        } else {
            [self fetchDone];
        }
        
    } else {
        [self startDoneWebResource];
    }
}

@end
